# -*- coding:utf-8 -*- 
# Linux32 module: build syscalls for linux 32 bits 

from ropgenerator.exploit.syscalls.SyscallDef import Syscall, ArgType
from ropgenerator.exploit.HighLevelUtils import popMultiple, build_call
from ropgenerator.IO import verbose, string_bold, string_ropg, string_payload, error
from ropgenerator.semantic.Engine import search
from ropgenerator.Database import QueryType
from ropgenerator.Constraints import Constraint, Assertion
import ropgenerator.Architecture as Arch

mprotect =   Syscall('int', 'mprotect', \
    [('void*', 'addr'),('size_t','len'),('int','prot')], [ArgType.INT,ArgType.INT,ArgType.INT],\
    ['rdi', 'rsi', 'rdx'], [('rax', 10)])

execve = Syscall('int', 'execve', \
    [('char*', 'cmd'),('char**','argv'),('char**', 'envp')], [ArgType.INT_OR_STRING, ArgType.INT,ArgType.INT],\
    ['rdi','rsi','rdx'], [('rax', 59)] )

read = Syscall('int', 'read', \
    [('unsigned int','fd'),('char*','buf'),('size_t','count')], [ArgType.INT, ArgType.INT_OR_STRING, ArgType.INT], \
    ['rdi', 'rsi', 'rdx'], [('rax', 0)])
    
write = Syscall('int', 'write', \
    [('unsigned int','fd'),('const char*','buf'),('size_t','count')], [ArgType.INT, ArgType.INT, ArgType.INT], \
    ['rdi', 'rsi', 'rdx'], [('rax', 1)])

chmod = Syscall('int', 'chmod', \
    [('const char*','filename'),('mode_t','mode')], [ArgType.INT_OR_STRING, ArgType.INT], \
    ['rdi', 'rsi'], [('rax',90)])
    
setuid = Syscall('int', 'setuid', \
    [('uid_t', 'uid')], [ArgType.INT], \
    ['rdi'], [('rax',105)])
    
    
mmap = Syscall('void*', 'mmap', \
    [('unsigned long','addr'),('unsigned long','len'),('unsigned long','prot'),('unsigned long','flags'),\
        ('unsigned long','fd'),('unsigned long ','off')],\
    [ArgType.INT, ArgType.INT, ArgType.INT, ArgType.INT, ArgType.INT, ArgType.INT], \
    ['rdi', 'rsi', 'rdx', 'r10', 'r8', 'r9'], [('rax',9)])

# MMAP with flags = MAP_ANONYMOUS (no fd and offset)
mmap_anon = Syscall('void*', 'mmap_anon', \
    [('unsigned long','addr'),('unsigned long','len'),('unsigned long','prot')],\
    [ArgType.INT, ArgType.INT, ArgType.INT], \
    ['rdi', 'rsi', 'rdx'], [('rax',9), ('r10', 0x20)], function="mmap")
   
syscalls_list = [mprotect, execve, read, write, chmod, setuid, mmap, mmap_anon]
    
## All available syscalls 
available = dict()
for syscall_object in syscalls_list:
    available[syscall_object.name()] = syscall_object

def supported(syscall_name):
    return (syscall_name in available)

def getSyscall(syscall_name):
    return available[syscall_name]
    
####################
# Useful functions #
####################
def print_available():
    global available
    print(string_bold("\n\n\tSupported Linux 64-bits syscalls"))
    print("\t--------------------------------")
    for name,syscall in available.iteritems():
        print("\n\t"+string_payload(name)+":  "+str(syscall))
